Skip to main content

Workflow Parallel Template

The Workflow Parallel template demonstrates how a BindAI workflow can fan out from one node into multiple workflow paths and synchronize those paths with a JoinNode. A ParallelNode acts as a branching point. The workflow executor adds all of the node’s outgoing next_nodes to the execution queue. A JoinNode can then track how many branch arrivals have reached it before allowing execution to continue.
Important: The current ParallelNode is a workflow fan-out mechanism. It does not create separate workflow contexts or launch branches in separate threads by itself.

Purpose

This template demonstrates how to:
  • Create multiple workflow branches
  • Fan out execution from a ParallelNode
  • Process branch nodes through the workflow executor
  • Synchronize branches with a JoinNode
  • Track branch-specific results in workflow variables
  • Coordinate independent workflow operations

Workflow Structure

A typical parallel workflow can be represented as:
The ParallelNode provides the branching point. The JoinNode provides synchronization after the branches reach it. There is no special built-in StartNode or EndNode required for this pattern.

ParallelNode

A parallel node can be created with:
The node itself does not contain branch-specific logic. Its execute() method simply returns the existing workflow context:
The workflow executor determines what happens next from the node’s next_nodes.

Fan-Out Execution

When the workflow executor completes a node, it normally adds that node’s next_nodes to the execution queue. For a ParallelNode, this means multiple outgoing nodes can be scheduled:
The executor processes the queued nodes through its normal execution loop. The ParallelNode itself does not start threads or create independent workflow executions.

Execution Model

The current execution model is better understood as workflow fan-out rather than automatic concurrent execution. Conceptually:
Each branch remains part of the same workflow execution and uses the same workflow context. This is important when designing branch logic.

Independent Branches

Parallel-style branching is useful when several operations do not depend directly on one another. For example:
Each branch can perform its own operation before reaching a synchronization point. A workflow with a direct dependency should normally express that dependency sequentially:

JoinNode

A JoinNode synchronizes branch arrivals. It is created with an expected number of arrivals:
The expected value determines how many times the join must be reached before it stops waiting. For three branch arrivals:

Join State

The JoinNode keeps track of arrivals using:
The join uses its own node ID as the state key. Conceptually:
After another arrival:
When the expected number of arrivals has been reached, the join removes its state entry.

Waiting

When the number of arrivals is still below expected, the JoinNode sets:
This indicates that the workflow is waiting for additional branch arrivals. When the expected count is reached:
The join state for that node is also removed. The workflow executor has special handling for JoinNode waiting states so that branch completion does not behave like a normal workflow-wide wait.

Shared Workflow Context

Parallel branches use the same workflow context. Conceptually:
This means branches can read and write shared workflow variables. For example:
A later node can read those values:

Avoiding Conflicting Writes

Because branches share workflow state, branch-specific data should generally use separate variable names. Prefer:
rather than having multiple branches overwrite:
A useful pattern is:
Then a downstream node can consume the collected values.

Combining Results

The JoinNode does not combine branch results. Its responsibility is synchronization. For example:
The downstream node is responsible for reading and combining the branch results.

Example

A multi-step analysis workflow could be structured as:
The research and analysis branches can write their results to separate workflow variables. The Join waits for the expected branch arrivals. The Summary Agent can then consume the collected values.

Configuring Branches

The ParallelNode uses the normal WorkflowNode.next_nodes mechanism. Conceptually:
The workflow executor will add those node IDs to the execution queue after the parallel node completes. The exact way nodes are connected depends on the workflow builder or node configuration being used.

Configuring the Join

For three branch arrivals:
The expected count should correspond to the number of branch paths that are intended to reach that particular join. For example:
The join waits until its arrival count reaches three.

Join Arrival Counting

Every time the JoinNode executes, it increments its arrival count:
If:
the join enters its waiting state. When:
the join resets its stored arrival state and clears the waiting flag.

Parallel vs Sequential

Parallel-style fan-out is useful when several branches can be represented independently.

Sequential

Each task follows the previous task.

Fan-Out

The fan-out model allows several workflow paths to be scheduled from the same point. However, the current implementation does not make those paths concurrent automatically.

Parallel vs Condition

A condition selects one of two configured paths. A parallel node schedules all of its outgoing paths. A condition is appropriate when only one path should execute. A parallel node is appropriate when multiple paths should be processed.

Synchronization with Join

A Join node is useful when downstream execution should wait for multiple branch arrivals. Conceptually:
With:
the first arrival causes the join to wait. The second arrival reaches the expected count and clears the waiting state.

Error Handling

ParallelNode and JoinNode do not implement their own branch-specific failure strategy. Exceptions raised by workflow nodes are handled by WorkflowExecutor. If no retry policy is configured, a node failure causes workflow failure. If a retry policy is configured, the executor can retry the failing node until its configured attempt limit is reached. The current parallel implementation should therefore not be described as automatically isolating failed branches or producing partial results.

Combining with Retry

A branch can participate in normal workflow retry behavior. Conceptually:
Retry behavior belongs to the workflow executor and retry policy, not to ParallelNode.

Combining with Timeout

Timeout policies are also handled by the workflow executor. A parallel-style workflow can therefore use timeout configuration around its normal node execution. For example:
The timeout mechanism remains part of workflow execution rather than the ParallelNode itself.

Typical Use Cases

This pattern can be useful for:
  • Independent analysis steps
  • Multiple retrieval operations
  • Separate validation paths
  • Independent API operations
  • Multi-agent analysis
  • Document-processing branches
  • Data preparation steps
  • Workflows that collect several results before continuing
The branches should be designed so that their shared-context interactions are predictable.

Important Implementation Boundaries

No separate workflow contexts

The current ParallelNode does not create a new WorkflowContext for each branch. All branches operate on the workflow’s existing context.

No automatic threads

The ParallelNode does not create threads or use a thread pool. It simply returns the context. The workflow executor schedules the node’s outgoing next_nodes.

Branches share variables

Because branches use the same context, writes to shared variables can interact with one another. Use branch-specific variable names where appropriate.

Join counts arrivals

JoinNode tracks arrivals using:
Each execution increments the count.

Join does not merge results

The Join synchronizes branch arrivals. It does not combine, transform, or summarize branch outputs.

Expected count must match the workflow

The expected value should represent the number of branch arrivals that the workflow intends to synchronize. An incorrect value can cause the join to wait for an arrival that never occurs or to release before all intended branches have arrived.

Best Practices

  • Use parallel fan-out only when multiple paths can be handled independently.
  • Configure branch-specific result variables.
  • Avoid conflicting writes to shared workflow variables.
  • Set JoinNode.expected to the intended number of arrivals.
  • Ensure every expected branch can actually reach the join.
  • Use a Join when downstream work depends on multiple branch arrivals.
  • Keep branch logic focused.
  • Use retry policies for transient node failures.
  • Test each branch independently.
  • Test the complete fan-out and synchronization path.
  • Remember that the current ParallelNode is fan-out scheduling, not automatic concurrent execution.

Related Templates

The parallel workflow pattern builds on:
  • 08.1 workflow-basic.md
  • 08.2 workflow-condition.md
  • 08.3 workflow-loop.md
It can also be combined with:
  • 08.5 workflow-human.md
  • 08.6 workflow-retry.md
  • 08.7 workflow-timeout.md
  • 08.8 workflow-schedule.md

Summary

The Workflow Parallel template introduces fan-out and synchronization into BindAI workflows. The essential pattern is:
A ParallelNode provides the branching point by allowing all of its outgoing next_nodes to be added to the workflow execution queue. A JoinNode tracks how many branch arrivals have reached it. Until the configured expected count is reached, the join enters a waiting state. Branches use the same workflow context, so branch-specific results should be stored carefully. The current implementation provides workflow-level fan-out and synchronization; it does not create independent workflow contexts or automatically execute branches concurrently.